package net.bat.entity;

import java.lang.reflect.Field;
import java.lang.reflect.Type;
import java.util.Date;

/**
 * 
 * @author c4w
 *         用于辅助生成前端Extjs代码
 *         用法:
 *         1.利用本工具,指定Class生成前端 model fields\grid columns\detail layout
 *         2.前端找一母本model,替换其名称和fields
 *         3.前端复制一view子目录
 *         分别替换grid columns\detail layout
 *         4.在nav tree中加入本grid id
 *         5.在Global.js中加入两句
 *         'XXXlist':{
 *         openobj:'onOpenObj'
 *         },
 *         'XXXdetail':{
 *         objnext:'objNext',
 *         objprev:'objPrev'
 *         },
 * 
 *         6.刷新界面&测试.
 *         7.细化:grid column和detail中的中文描述
 *         8.细化:grid中的filter
 *         9.细化:detail中的顺序,field type
 * 
 *
 */

public class ExtJSCoder {

	public static final String STR_SERIAL_VERSION_UID = "serialVersionUID";
	public static final String BIND_DEFAULT = "theObj";

	public static String printDetailFields(Class<?> cls, int cols, String bindTo, String[] fldNames) {
		String cn = cls.getSimpleName();
		String lcn = cn.toLowerCase();
		StringBuffer sbuf = new StringBuffer();
		if (bindTo == null) {
			bindTo = BIND_DEFAULT;
		}
		Field[] flds;
		if (fldNames == null) {
			flds = cls.getDeclaredFields();
		} else {
			flds = new Field[fldNames.length];
			for (int i = 0; i < fldNames.length; i++) {
				try {
					flds[i] = cls.getDeclaredField(fldNames[i]);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
					flds[i] = null;
				}
			}
		}
		int pos = 0;
		int pos_col = 0;
		int pos_row = 0;
		for (Field fld : flds) {
			if ((fld == null) || fld.getName().equals(STR_SERIAL_VERSION_UID)) {
				continue;
			}
			if (pos_col == 0) {
				if (pos_row > 0) {
					sbuf.append(",");
				} else {
					sbuf.append("Ext.define('DCApp.view." + lcn + ".Detail', {\n" + "extend: 'DCApp.view.Detail',\n"
							+ "alias: 'widget." + cn + "detail',\n" + "\n" + "bind: {\n"
							+ "title: '用户 - 【{theObj.id}】'\n" + "},\n" + "\n" + "componentCls: '" + lcn + "-detail',\n"
							+ "bodyPadding: 0,\n" + "\n" + "controller: 'detail',\n" + "\n"
							+ "afterRender: function(ct, position) {\n" + "this.callParent();\n" + "},\n"
							+ "items: [{\n" + "listeners: {\n" + "render: function(p){\n" + "p = p.getEl();\n"
							+ "var me= this.up();\n" + "me.h0=p.getHeight();\n" + "p.on('scroll', function(e, t){\n"
							+ "me.onscroll(t.scrollTop,t.clientHeight);\n" + "}, p);\n" + "}\n" + "},\n"
							+ "title: 'Panel 0',\n" + "flex: 2,\n" + "frame: false,\n" + "xtype: 'container',\n"
							+ "layout: 'anchor',\n" + "style: {\n" + "overflow: 'auto'\n" + "},\n" + "\n"
							+ "items: [\n" + "{\n" + "title : '详情',\n" + "margin : '0 0 10 0',\n"
							+ "cls : 'nav_pos',\n" + "reference : 'form',\n" + "bodyPadding : 10,\n"
							+ "fieldDefaults : {\n" + "labelAlign : 'right',\n" + "labelWidth : 100,\n"
							+ "padding : 3\n" + "},\n" + "defaults : {\n" + "anchor : '100%'\n" + "},\n"
							+ "xtype: 'form',\n" + "items: [\n");
				}
				sbuf.append("\n{\n" + "	xtype: 'container',\n" + "	layout: 'hbox',\n" + "	defaultType: 'textfield',\n"
						+ "	items:[\n");
				pos_row++;
			}
			if (pos_col > 0) {
				sbuf.append(",");
			}
			sbuf.append("	{\n" + "	flex: 1,\n" + "	fieldLabel: '" + fld.getName() + "',\n" + "	bind: '{" + bindTo + "."
					+ fld.getName() + "}'\n" + "	}");
			pos_col++;
			pos++;
			if (pos_col == cols) {
				sbuf.append("	]\n" + "}");
				pos_col = 0;
			}
		}
		// 非整除
		if (pos_col != 0) {
			sbuf.append("	]\n" + "}");

		}

		sbuf.append("]}]\n" + " }]\n" + "});\n");

		return sbuf.toString();
	}

	public static String printListModel(Class<?> cls) {
		String cn = cls.getSimpleName();
		String lcn = cn.toLowerCase();
		StringBuffer sbuf = new StringBuffer();
		sbuf.append("Ext.define('DCApp.view." + lcn + ".ListModel', {\n" + "	extend: 'Ext.app.ViewModel',\n"
				+ "	alias: 'viewmodel." + lcn + "list',\n" + "	requires: [\n" + "		'DCApp.model." + cn + "'\n"
				+ "	],\n" + "\n" + "	stores: {\n" + "		objs: {type:'PageStore',model: '" + cn + "'},\n"
				+ "		objsel: {type:'PageStore',model: '" + cn + "'}\n" + "	}\n" + "});\n");
		return sbuf.toString();
	}

	public static String printModelFields(Class<?> cls) {
		String cn = cls.getSimpleName();
		StringBuffer sbuf = new StringBuffer();
		Field[] flds = cls.getDeclaredFields();
		for (Field fld : flds) {
			String fldName = fld.getName();
			if (fldName.equals(STR_SERIAL_VERSION_UID)) {
				continue;
			}
			if (sbuf.length() > 0) {
				sbuf.append(",\n");
			} else {
				sbuf.append("Ext.define('DCApp.model." + cn + "', {\n" + "extend: 'DCApp.model.Base',\n"
						+ "fields: [\n");

			}
			Type t = fld.getType();
			sbuf.append("	{name:'" + fldName);
			if (t == String.class) {
				sbuf.append("'}");
			} else if (t == Date.class) {
				sbuf.append("', type: 'date'}");
			} else if (t == Boolean.class) {
				sbuf.append("', type: 'bool'}");
			} else {
				sbuf.append("', type: 'int'}");
			}
		}
		sbuf.append(" ]\n" + "});");
		return sbuf.toString();
	}

	public static String printGridColumns(Class<?> cls) {
		String cn = cls.getSimpleName();
		String lcn = cn.toLowerCase();

		StringBuffer sbuf = new StringBuffer();
		sbuf.append("Ext.define('DCApp.view." + lcn + ".List', {\n" + "extend: 'DCApp.view.PageList',\n"
				+ "alias: 'widget." + cn + "list',\n" + "\n" + "viewModel: {\n" + "	type: '" + lcn + "list'\n" + "},\n"
				+ "\n" + "columns: [\n");
		sbuf.append("{text:'id',dataIndex:'id', filter: 'number'}");
		Field[] flds = cls.getDeclaredFields();
		for (Field fld : flds) {
			String fldName = fld.getName();
			if (fldName.equals(STR_SERIAL_VERSION_UID)) {
				continue;
			}
			if (sbuf.length() > 0) {
				sbuf.append(",\n");
			}
			Type t = fld.getType();
			sbuf.append("{text:'" + fldName + "',dataIndex:'" + fldName);
			if (t == String.class) {
				sbuf.append("',filter:'string'}");
			} else if (t == Date.class) {
				sbuf.append("', xtype: 'datecolumn',filter:true}");
			} else if (t == Boolean.class) {
				sbuf.append("', filter: 'boolean'}");
			} else {
				sbuf.append("', filter: 'number'}");
			}
		}
		sbuf.append(" ]\n" + "});\n");
		return sbuf.toString();
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Class cls = Tag.class;
		String cn = cls.getSimpleName();
		String lcn = cn.toLowerCase();
		System.out.println("/*------------app/model/" + cn + ".js--------------*/");
		System.out.println(printModelFields(cls));
		System.out.println("\n\n/*-------------app/view/" + lcn + "/List.js-------------*/");
		System.out.println(printGridColumns(cls));
		System.out.println("\n\n/*-------------app/view/" + lcn + "/Detail.js-------------*/");
		System.out.println(printDetailFields(cls, 2, null, null));
		System.out.println("\n\n/*-------------app/view/" + lcn + "/ListModel.js-------------*/");
		System.out.println(printListModel(cls));
	}

}
